\chapter{Vérifications et tests}
\section{Benchmarks} \label{ref_benchmarks}

\paragraph{}Nous avons exécuté nos différents algorithmes sur plusieurs
entrées afin de pouvoir comparer les performances de chacun.

\paragraph{}Modélisation du temps d'exécution (secondes) en fonction
du nombre de MPS et de Threads par bloc sur l'image the\_eye.jpg (12800x12800).

\resizebox{12cm}{!}{

  \begin{tikzpicture}
    \begin{axis}[grid=major,
      xlabel=$MultiProcessorStream$,
      ylabel=$Temps (secondes)$]
      \addplot[smooth,mark=x,red] plot coordinates {
        (15,6.4)
        (30,4.7)
        (45,3.7)
      };
      \addlegendentry{96 threads}

      \addplot[smooth,color=green,mark=x]
      plot coordinates {
        (15,7.7)
        (30,5.7)
        (45,4.5)
      };
      \addlegendentry{64 threads}

      \addplot[smooth,color=blue,mark=x]
      plot coordinates {
        (15,13.7)
        (30,7.7)
        (45,6.3)
      };
      \addlegendentry{32 threads}
    \end{axis}
  \end{tikzpicture}

}

\begin{figure}[H]
\centering
\begin{tabular}{ l | c|  c | c | }
 threads / MPS& 32 & 64 & 96 \\ \hline
 15 & 13,7 & 7,7 & 6,3 \\ \hline
 30 & 7,7 & 5,7 & 4,5 \\ \hline
 45 & 6,4 & 4,7 & 3,7 \\
 \hline  
 \end{tabular}
\caption{Récapitulatif}
\end{figure}

\paragraph{}On constate que la couche d'émulation de CUDA est performante. En effet, elle permet d'optimiser le recouvrement des temps de transferts/calculs. Cela s'explique par le fait que lors d'un ``long'' calcul (relatif à une unité de calcul spécifique) dans un bloc, le scheduler\footnote{Ordonnanceur de tâches de la carte graphique.} va exécuter les instructions d'un autre bloc pendant ce temps. De cette façon, le temps passé à faire un calcul sur un bloc n'est pas perdu; au contraire, il sert à exécuter d'autres opérations. Par rapport à l'architecture physique de la carte, 32 Threads par blocks et 15 MPS, il est possible de gagner un facteur $3,7$ en passant à 96 threads et 45 MPS.

\begin{figure}[H]
\centering
\begin{tabular}{ l | c | c |}
image / type & 12800*12800 & 8211*8652 \\ \hline
Séquentiel & 70 & 30 \\ \hline
MultiThread (4) & 17,9 & 8,8 \\ \hline
CUDA & 3,7 & 1,7 \\
\hline
\end{tabular}
\caption{Temps d'exécution (sec) en fonction du type d'algorithme}
\end{figure}

\paragraph{}On constate que le gain en utilisant CUDA, par rapport à un
algorithme MultiThread avec 4 Threads, est interessant mais reste en
dessous de nos espérences.

\section{Vérification des résultats}
\paragraph{}Pour vérifier nos images de sortie après convolution, nous
avons utilisé $OCTAVE$ (un logiciel libre de calcul numérique). De
cette façon, il nous a été possible de valider notre programme en
comparant les deux images après application d'une détection de contours,
par exemple.

\section{Qu'en déduire ?}
\paragraph{}Nous observons que notre système est effectivement capable de gagner du temps en exploitant les possibilités de la carte graphique. Si ces gains n'étaient à l'origine (avec un paramétrage basé uniquement sur le matériel) pas si élevés, l'exploitation de la couche d'émulation CUDA de multi-processeurs et de threads nous a permis de très fortement augmenter ces gains.
\paragraph{}Nous supposons que les gains obtenus viennent du système de prefetching et de mise en cache effectué par CUDA pendant l'exécution du code, qui permet d'exécuter des calculs de manière asynchrones entre bloc de threads quand certains sont en attente de données ``lointaines''.
